Skip to content

Method: static {...}

1: /*
2: * JOPA
3: * Copyright (C) 2024 Czech Technical University in Prague
4: *
5: * This library is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public
7: * License as published by the Free Software Foundation; either
8: * version 3.0 of the License, or (at your option) any later version.
9: *
10: * This library is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this library.
17: */
18: package cz.cvut.kbss.ontodriver.jena;
19:
20: import cz.cvut.kbss.ontodriver.descriptor.AxiomDescriptor;
21: import cz.cvut.kbss.ontodriver.jena.connector.StorageConnector;
22: import cz.cvut.kbss.ontodriver.model.Assertion;
23: import cz.cvut.kbss.ontodriver.model.Axiom;
24: import cz.cvut.kbss.ontodriver.model.AxiomImpl;
25: import cz.cvut.kbss.ontodriver.model.Value;
26: import cz.cvut.kbss.ontodriver.util.Vocabulary;
27: import org.apache.jena.rdf.model.*;
28:
29: import java.net.URI;
30: import java.util.*;
31: import java.util.stream.Collectors;
32:
33: class ExplicitAxiomLoader extends AbstractAxiomLoader {
34:
35: private static final Assertion UNSPECIFIED_ASSERTION = Assertion.createUnspecifiedPropertyAssertion(false);
36:
37: private final StorageConnector connector;
38:
39: private Map<String, Assertion> assertedProperties;
40: private Assertion unspecifiedProperty;
41:
42: ExplicitAxiomLoader(StorageConnector connector) {
43: this.connector = connector;
44: }
45:
46: @Override
47: boolean contains(Resource subject, Property property, RDFNode object, Set<URI> contexts) {
48: return connector
49: .contains(subject, property, object, contexts.stream().map(URI::toString).collect(Collectors.toSet()));
50: }
51:
52: @Override
53: Collection<Axiom<?>> find(AxiomDescriptor descriptor, Map<String, Assertion> assertions) {
54: this.assertedProperties = assertions;
55: this.unspecifiedProperty = resolveUnspecifiedProperty();
56: final Resource subject = ResourceFactory.createResource(descriptor.getSubject().getIdentifier().toString());
57: final Collection<Statement> statements = findStatements(subject, null, descriptor.getSubjectContexts());
58: final List<Axiom<?>> result = transformStatementsToAxioms(descriptor, statements);
59: result.addAll(loadAxiomsForPropertiesInContext(descriptor, subject));
60: return result;
61: }
62:
63: private Assertion resolveUnspecifiedProperty() {
64: final Optional<Assertion> unspecified =
65: assertedProperties.values().stream().filter(a -> a.equals(UNSPECIFIED_ASSERTION)).findAny();
66: return unspecified.orElse(null);
67: }
68:
69: @Override
70: Collection<Statement> findStatements(Resource subject, Property property, Collection<URI> contexts) {
71: return connector
72: .find(subject, property, null, contexts.stream().map(URI::toString).collect(Collectors.toSet()));
73: }
74:
75: private List<Axiom<?>> transformStatementsToAxioms(AxiomDescriptor descriptor, Collection<Statement> statements) {
76: final List<Axiom<?>> axioms = new ArrayList<>(statements.size());
77: for (Statement statement : statements) {
78: final Property property = statement.getPredicate();
79: if (shouldSkipProperty(property, descriptor)) {
80: continue;
81: }
82: final Assertion a =
83: assertedProperties.containsKey(property.getURI()) ? assertedProperties.get(property.getURI()) :
84: createAssertionForStatement(statement);
85: final Optional<Value<?>> value = resolveValue(a, statement.getObject());
86: value.ifPresent(v -> axioms.add(new AxiomImpl<>(descriptor.getSubject(), a, v)));
87: }
88: return axioms;
89: }
90:
91: private boolean shouldSkipProperty(Property property, AxiomDescriptor descriptor) {
92: final String propertyUri = property.getURI();
93: // If the property is not mapped and either there is not the unspecified property or the property is rdf:type,
94: // which is handled by Types
95: if (!assertedProperties.containsKey(propertyUri) && (unspecifiedProperty == null || propertyUri
96: .equals(Vocabulary.RDF_TYPE))) {
97: return true;
98: }
99: final Assertion a = assertedProperties.getOrDefault(propertyUri, unspecifiedProperty);
100: return !assertionContextMatchesSubject(descriptor.getSubjectContexts(), descriptor.getAssertionContexts(a));
101: }
102:
103: private List<Axiom<?>> loadAxiomsForPropertiesInContext(AxiomDescriptor descriptor, Resource subject) {
104: final List<Axiom<?>> axioms = new ArrayList<>();
105: for (Assertion a : assertedProperties.values()) {
106: final Set<URI> assertionCtx = descriptor.getAssertionContexts(a);
107: if (assertionContextMatchesSubject(descriptor.getSubjectContexts(), assertionCtx)) {
108: continue;
109: }
110: final Property property = ResourceFactory.createProperty(a.getIdentifier().toString());
111: final Collection<Statement> statements = findStatements(subject, property, assertionCtx);
112: statements.forEach(statement -> {
113: final Optional<Value<?>> value = resolveValue(a, statement.getObject());
114: value.ifPresent(v -> axioms.add(new AxiomImpl<>(descriptor.getSubject(), a, v)));
115: });
116: }
117: if (unspecifiedProperty != null && !assertionContextMatchesSubject(descriptor.getSubjectContexts(),
118: descriptor.getAssertionContexts(unspecifiedProperty))) {
119: final Collection<Statement> statements =
120: findStatements(subject, null, descriptor.getAssertionContexts(unspecifiedProperty));
121: for (Statement s : statements) {
122: final Assertion a = createAssertionForStatement(s);
123: final Optional<Value<?>> value = resolveValue(a, s.getObject());
124: value.ifPresent(v -> axioms.add(new AxiomImpl<>(descriptor.getSubject(), a, v)));
125: }
126: }
127: return axioms;
128: }
129:
130: private static boolean assertionContextMatchesSubject(Set<URI> subjectCtx, Set<URI> assertionCtx) {
131: return (subjectCtx.isEmpty() && assertionCtx.isEmpty()) ||
132: (!subjectCtx.isEmpty() && assertionCtx.stream().anyMatch(subjectCtx::contains));
133: }
134: }